package org.example.reflect_demo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 反射操作实践案例（优化逻辑版）
 */
public class ReflectionOperationDemo {
    public static void main(String[] args) throws Exception {
        // ==================== 阶段一：初始化与类加载 ====================
        // 1. 获取目标类的Class对象（反射的入口）
        Class<?> userClass = Class.forName("org.example.reflect_demo.User");
        System.out.println("[阶段一] 成功加载类: " + userClass.getName());

        // 2. 动态创建对象（基于Class对象实例化）
        Object user = userClass.newInstance();
        System.out.println("[阶段一] 成功创建实例: " + user.getClass().getSimpleName() + "\n");


        // ==================== 阶段二：公共方法调用 ====================
        System.out.println("===== 阶段二：公共方法操作 =====");
        // 3. 调用setter方法设置初始属性
        Method setNameMethod = userClass.getMethod("setName", String.class);
        Method setAgeMethod = userClass.getMethod("setAge", int.class);
        setNameMethod.invoke(user, "张三");
        setAgeMethod.invoke(user, 28);
        System.out.println("3. 已通过setter设置初始属性: 姓名=张三, 年龄=28");

        // 4. 调用getter方法验证属性设置结果
        Method getNameMethod = userClass.getMethod("getName");
        Method getAgeMethod = userClass.getMethod("getAge");
        String name = (String) getNameMethod.invoke(user);
        int age = (int) getAgeMethod.invoke(user);
        System.out.println("4. getter验证结果: 姓名=" + name + ", 年龄=" + age);

        // 5. 调用自定义公共方法更新信息
        Method updateInfoMethod = userClass.getMethod("updateInfo", String.class, int.class);
        updateInfoMethod.invoke(user, "李四", 30);
        System.out.println("5. 调用updateInfo后: 姓名=" + getNameMethod.invoke(user) + ", 年龄=" + getAgeMethod.invoke(user) + "\n");


        // ==================== 阶段三：私有成员操作 ====================
        System.out.println("===== 阶段三：私有成员操作 =====");
        // 6. 调用私有方法（需突破访问限制）
        Method printInfoMethod = userClass.getDeclaredMethod("printInfo");
        printInfoMethod.setAccessible(true); // 开启私有方法访问权限
        System.out.print("6. 调用私有方法printInfo: ");
        printInfoMethod.invoke(user); // 执行私有方法

        // 7. 直接修改私有属性（绕过setter方法）
        Field nameField = userClass.getDeclaredField("name");
        nameField.setAccessible(true); // 开启私有属性访问权限
        nameField.set(user, "王五"); // 直接修改内存中的属性值
        System.out.println("7. 直接修改私有属性后: 姓名=" + nameField.get(user) + "\n");


        // ==================== 阶段四：公共属性操作 ====================
        System.out.println("===== 阶段四：公共属性操作 =====");
        // 8. 操作公共属性（无需特殊权限）
        Field genderField = userClass.getField("gender");
        genderField.set(user, "男");
        System.out.println("8. 设置公共属性结果: gender=" + genderField.get(user));

        System.out.println("\n[全部操作完成] 反射流程执行结束");
    }
}